doc: Add FAQ
This patch introduces a new FAQ, and adds some FAQ-like info inline to doctrings where appropriate. NOTES.md is no longer necessary now that we have its content properly documented, and so it was removed.
This commit is contained in:
		
							
								
								
									
										33
									
								
								NOTES.md
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								NOTES.md
									
									
									
									
									
								
							@@ -1,33 +0,0 @@
 | 
			
		||||
### Assumptions ###
 | 
			
		||||
 | 
			
		||||
In order to stay lean and fast, Falcon makes several assumptions.
 | 
			
		||||
 | 
			
		||||
First, Falcon assumes that resource responders will (for the most part) do the right thing. In other words, Falcon doesn't try very hard to protect responder code from itself.
 | 
			
		||||
 | 
			
		||||
This requires some discipline on the part of the developer.
 | 
			
		||||
 | 
			
		||||
1. Resource responders set response variables to sane values.
 | 
			
		||||
1. All code is well-tested, with high code coverage. It's not Falcon's job to babysit.
 | 
			
		||||
1. Anticipate and handle exceptions. Falcon only expects HTTPError exception types to be thrown from responders.
 | 
			
		||||
 | 
			
		||||
### Misc. ###
 | 
			
		||||
 | 
			
		||||
* Falcon is probably thread-safe, but this has yet to be verified. Caveat emptor.
 | 
			
		||||
* For 204, just set the status and no body. Falcon will ignore the body even if you set it.
 | 
			
		||||
* If you set resp.body to a Unicode string, Falcon will attempt to encode it as UTF-8 before sending the content to the WSGI server (as required by PEP-333). If you already have encoded data (or it's a binary blob), use resp.data instead (it's faster).
 | 
			
		||||
* Default media type (returned as the value of the 'Content-Type' header) for responses is 'application/json; charset=utf-8' (falcon.DEFAULT\_MEDIA\_TYPE), and the default status is '200 OK.' You can set a custom media type in the API constructor to save yourself from having to always set Content-Type for each request.
 | 
			
		||||
* resp.set_header assumes both params are strings. App may crash otherwise. Falcon trusts the caller. You *are* testing all your code paths, aren't you?
 | 
			
		||||
* If you need the protocol (http vs https) to construct hrefs in your responses (hypermedia is good, trust me), you can get it from req.scheme
 | 
			
		||||
* URI template and query string field names must include only ASCII a-z, A-Z, and the underscore '_' character. Try it; you'll like it. This simplifies parsing and helps speed things up a bit.
 | 
			
		||||
* on_* responder methods in a resource class must define all URI template field names for any route attached to that resource. If they do not, Falcon will raise an error. You might see this if you attempt to have a single OxResource that you try to overload to respond to both, e.g., "PUT /oxen/old-ben" and "GET /oxen". Resist the temptation to overload your resources; instead, create OxResource and OxenResource. It is common to put these two classes in the same module.
 | 
			
		||||
* Query params must have a value. In other words, 'foo' or 'foo=' will result in the parameter being ignored.
 | 
			
		||||
* If the WSGI server passes an empty path, Falcon will force it to '/', so you don't have to test for the empty string in your app.
 | 
			
		||||
* The routes '/foo/bar' and '/foo/bar/' are identical as far as Falcon is concerned. Requests coming in for either will be sent to the same resource.
 | 
			
		||||
* If you are hosting multiple apps with a single WSGI server, the SCRIPT_NAME variable can be read from req.app
 | 
			
		||||
* If you have several headers to set, consider using set_headers to avoid function call overhead
 | 
			
		||||
* Don't set content-length. It will only be overridden.
 | 
			
		||||
* The order in which header fields are sent in the response is undefined. Headers are not grouped according to the recommendation in [RFC 2616](http://tools.ietf.org/html/rfc2616#section-4.2) in order to generate responses as quickly as possible.
 | 
			
		||||
* Header names are case-insensitive in req.get_header
 | 
			
		||||
* For streaming large items, assign a generator or IO object to resp.stream. If you know the file size in advance, assign it to stream\_len. For dynamically-generated content, leave off stream\_len, and Falcon will then leave off the Content-Length header, and hopefully your WSGI server will do the right thing, assuming you've told it to enable keep-alive (PEP-333 prohibits apps from setting hop-by-hop headers itself, such as Transfer-Encoding).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -55,7 +55,7 @@ master_doc = 'index'
 | 
			
		||||
 | 
			
		||||
# General information about the project.
 | 
			
		||||
project = u'Falcon'
 | 
			
		||||
copyright = u'2014, Kurt Griffiths'
 | 
			
		||||
copyright = u'2014, Kurt Griffiths and Rackspace Hosting'
 | 
			
		||||
 | 
			
		||||
# The version info for the project you're documenting, acts as replacement for
 | 
			
		||||
# |version| and |release|, also used in various other places throughout the
 | 
			
		||||
@@ -189,7 +189,7 @@ html_sidebars = {
 | 
			
		||||
#html_show_sphinx = True
 | 
			
		||||
 | 
			
		||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
 | 
			
		||||
#html_show_copyright = True
 | 
			
		||||
html_show_copyright = False
 | 
			
		||||
 | 
			
		||||
# If true, an OpenSearch description file will be output, and all pages will
 | 
			
		||||
# contain a <link> tag referring to it.  The value of this option must be the
 | 
			
		||||
 
 | 
			
		||||
@@ -73,6 +73,7 @@ Resources
 | 
			
		||||
---------
 | 
			
		||||
 | 
			
		||||
- `The Definitive Introduction to Falcon <https://speakerdeck.com/cabrera/the-definitive-introduction-to-falcon>`_
 | 
			
		||||
- `An Unladen Web Framework <http://blog.kgriffs.com/2013/07/02/python-fast-web-service-framework.html>`_.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
User Guide
 | 
			
		||||
@@ -85,6 +86,7 @@ User Guide
 | 
			
		||||
   user/install
 | 
			
		||||
   user/quickstart
 | 
			
		||||
   user/tutorial
 | 
			
		||||
   user/faq
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. Community Guide
 | 
			
		||||
 
 | 
			
		||||
@@ -5,4 +5,7 @@
 | 
			
		||||
.. error responses for auth - 404 ?
 | 
			
		||||
.. error hooks
 | 
			
		||||
.. document all the individual error classes?
 | 
			
		||||
.. stacked hooks
 | 
			
		||||
.. stacked hooks
 | 
			
		||||
.. auth whitelist
 | 
			
		||||
.. processing file uploads from forms
 | 
			
		||||
.. static file serving
 | 
			
		||||
							
								
								
									
										8
									
								
								doc/user/deployment.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								doc/user/deployment.rst
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
.. _deployment:
 | 
			
		||||
 | 
			
		||||
Deploying Your Web API
 | 
			
		||||
======================
 | 
			
		||||
 | 
			
		||||
[talk about, diagram async, host, etc.]
 | 
			
		||||
 | 
			
		||||
[async front, async to backend options - asyncio, gevent, etc.]
 | 
			
		||||
							
								
								
									
										142
									
								
								doc/user/faq.rst
									
									
									
									
									
								
							
							
						
						
									
										142
									
								
								doc/user/faq.rst
									
									
									
									
									
								
							@@ -0,0 +1,142 @@
 | 
			
		||||
.. _faq:
 | 
			
		||||
 | 
			
		||||
Questions & Answers
 | 
			
		||||
===================
 | 
			
		||||
 | 
			
		||||
Is Falcon thread-safe?
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
New Request and Response objects are created for each incoming HTTP request.
 | 
			
		||||
However, a single instance of each resource class attached to a route is
 | 
			
		||||
shared among all requests. Therefore, as long as you are careful about the
 | 
			
		||||
way responders access class member variables to avoid conflicts, your
 | 
			
		||||
WSGI app should be thread-safe.
 | 
			
		||||
 | 
			
		||||
That being said, Falcon-based services are usually deployed using green
 | 
			
		||||
threads (via the gevent library or similar) which aren't truly running
 | 
			
		||||
concurrently, so there may be some edge cases where Falcon is not
 | 
			
		||||
thread-safe that haven't been discovered yet.
 | 
			
		||||
 | 
			
		||||
*Caveat emptor!*
 | 
			
		||||
 | 
			
		||||
Why doesn't Falcon create a new Resource instance for every request?
 | 
			
		||||
----
 | 
			
		||||
Falcon generally tries to minimize the number of objects that it
 | 
			
		||||
instantiates. It does this for two reasons: first, to avoid the expense of
 | 
			
		||||
creating the object, and second to mitigate memory fragmentation.
 | 
			
		||||
 | 
			
		||||
Therefore, when adding a route, Falcon requires an *instance* of your
 | 
			
		||||
resource class, rather than the class type. That same instance will be used
 | 
			
		||||
to server all requests coming in on that route.
 | 
			
		||||
 | 
			
		||||
How can I pass data from a hook to a responders, and between hooks?
 | 
			
		||||
----
 | 
			
		||||
You can inject extra responder kwargs from a hook by adding them
 | 
			
		||||
to the *params* dict passed into the hook. You can also add custom data to
 | 
			
		||||
the req.env WSGI dict, as a way of passing contextual information around.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
    Falcon 0.2 will add a dict to Request to provide a cleaner alternative to
 | 
			
		||||
    using req.env.
 | 
			
		||||
 | 
			
		||||
Does Falcon set Content-Length or do I need to do that explicitly?
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
Falcon will try to do this for you, based on the value of `resp.body`,
 | 
			
		||||
`resp.data`, or `resp.stream_len` (whichever is set in the response, checked
 | 
			
		||||
in that order.)
 | 
			
		||||
 | 
			
		||||
For dynamically-generated content, you can choose to leave off `stream_len`,
 | 
			
		||||
in which case Falcon will then leave off the Content-Length header, and
 | 
			
		||||
hopefully your WSGI server will do the Right Thing™ (assuming you've told
 | 
			
		||||
it to enable keep-alive).
 | 
			
		||||
 | 
			
		||||
.. note:: PEP-333 prohibits apps from setting hop-by-hop headers itself,
 | 
			
		||||
    such as Transfer-Encoding.
 | 
			
		||||
 | 
			
		||||
I'm setting a response body, but it isn't getting returned. What's going on?
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
Falcon skips processing the response body to save a few cycles when the HTTP
 | 
			
		||||
spec defines that the response should *have* no body. First, if the client
 | 
			
		||||
sends a HEAD request, the response body will be empty. Second, if the response
 | 
			
		||||
status set by a resource is one of the following, Falcon will skip processing
 | 
			
		||||
the response body::
 | 
			
		||||
 | 
			
		||||
    falcon.HTTP_100
 | 
			
		||||
    falcon.HTTP_204
 | 
			
		||||
    falcon.HTTP_416
 | 
			
		||||
    falcon.HTTP_304
 | 
			
		||||
 | 
			
		||||
Why does raising an error inside a resource crash my app?
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
Generally speaking, Falcon assumes that resource responders (such as *on_get*,
 | 
			
		||||
*on_post*, etc.) will, for the most part, do the right thing. In other words,
 | 
			
		||||
Falcon doesn't try very hard to protect responder code from itself.
 | 
			
		||||
 | 
			
		||||
This approach reduces the number of (often) extraneous checks that Falcon
 | 
			
		||||
would otherwise have to perform, making the framework more efficient. With
 | 
			
		||||
that in mind, writing a high-quality API based on Falcon requires that:
 | 
			
		||||
 | 
			
		||||
#. Resource responders set response variables to sane values.
 | 
			
		||||
#. Your code is well-tested, with high code coverage.
 | 
			
		||||
#. Errors are anticipated, detected, and handled appropriately within
 | 
			
		||||
   each responder and with the aid of custom error handlers.
 | 
			
		||||
 | 
			
		||||
.. note:: Falcon will re-raise errors that do not inherit from
 | 
			
		||||
    ``falcon.HTTPError`` unless you have registered a custom error
 | 
			
		||||
    handler for that type (see also: :ref:`falcon.API <api>`).
 | 
			
		||||
 | 
			
		||||
Why are trailing slashes trimmed from req.path?
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
Falcon normalizes incoming URI paths to simplify later processing and
 | 
			
		||||
improve the predictability of application logic. In addition to stripping
 | 
			
		||||
a trailing slashes, if any, Falcon will convert empty paths to '/'.
 | 
			
		||||
 | 
			
		||||
Note also that routing is also normalized, so adding a route for '/foo/bar'
 | 
			
		||||
also implicitly adds a route for '/foo/bar/'. Requests coming in for either
 | 
			
		||||
path will be sent to the same resource.
 | 
			
		||||
 | 
			
		||||
Why are field names in URI templates restricted to certain characters?
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
Field names are restricted to the ASCII characters a-z, A-Z, and '_'. Using a
 | 
			
		||||
restricted set of characters reduces the overhead of parsing incoming
 | 
			
		||||
requests.
 | 
			
		||||
 | 
			
		||||
Why is my query parameter missing from the req object?
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
If a query params does not have a value, Falcon will treat it as though the
 | 
			
		||||
param were omitted completely from the URI. For example, 'foo' or 'foo=' will
 | 
			
		||||
result in the parameter being ignored.
 | 
			
		||||
 | 
			
		||||
Is there a way for me to ensure headers are sent to clients in a specific order?
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
In order to generate HTTP responses as quickly as possible, Falcon does not
 | 
			
		||||
try to sort or even logically group related headers in the HTTP response.
 | 
			
		||||
 | 
			
		||||
.. note about stream being consumed for 'application/x-www-form-urlencoded’
 | 
			
		||||
 | 
			
		||||
.. If Falcon is designed for building web APIs, why does it support forms?
 | 
			
		||||
.. ----
 | 
			
		||||
.. Doesn't support files, allows same code to handle both...
 | 
			
		||||
 | 
			
		||||
.. What happens if an error is raised from a hook?
 | 
			
		||||
.. ----
 | 
			
		||||
.. Falcon will catch the error, and do one of three things:
 | 
			
		||||
 | 
			
		||||
.. 1. If the error is an instance of *HTTPError* (or a child of *HTTPError*), Falcon will convert it to an HTTP response and return that to the client.
 | 
			
		||||
.. 2. If there is a custom error handler, that will be called and given a chance to clean up resources and set up the Response object. When the handler returns, Falcon will immediately return a response to the client.
 | 
			
		||||
.. 3. If the type is unrecognized, it is re-raised and will be handled by your WSGI server.
 | 
			
		||||
 | 
			
		||||
.. Note that when an error is raised, it short-circuits the normal request chain.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. Coming soon: before vs. after... work to catch HTTPError and other handlers, and set resp,
 | 
			
		||||
.. then continue with after hooks so can DRY up logic you want to run when an
 | 
			
		||||
.. error occurs. For example, serialize error to a normalized response body
 | 
			
		||||
.. scheme.
 | 
			
		||||
@@ -569,17 +569,35 @@ for information that will help them crack your API.
 | 
			
		||||
Error Handling
 | 
			
		||||
--------------
 | 
			
		||||
 | 
			
		||||
When something goes horribly (or mildly) wrong, you *could* manually set the
 | 
			
		||||
error status, appropriate response headers, and even an error body using the
 | 
			
		||||
``resp`` object. However, Falcon tries to make things a bit easier by
 | 
			
		||||
providing a set of exceptions you can raise when something goes wrong. In fact,
 | 
			
		||||
if Falcon catches any exception your responder throws that inherits from
 | 
			
		||||
``falcon.HTTPError``, the framework will convert that exception to an
 | 
			
		||||
appropriate HTTP error response.
 | 
			
		||||
Generally speaking, Falcon assumes that resource responders (*on_get*,
 | 
			
		||||
*on_post*, etc.) will, for the most part, do the right thing. In other words,
 | 
			
		||||
Falcon doesn't try very hard to protect responder code from itself.
 | 
			
		||||
 | 
			
		||||
This approach reduces the number of (often) extraneous checks that Falcon
 | 
			
		||||
would otherwise have to perform, making the framework more efficient. With
 | 
			
		||||
that in mind, writing a high-quality API based on Falcon requires that:
 | 
			
		||||
 | 
			
		||||
1. Resource responders set response variables to sane values.
 | 
			
		||||
1. Your code is well-tested, with high code coverage.
 | 
			
		||||
1. Errors are anticipated, detected, and handled appropriately within each
 | 
			
		||||
responder.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
    Falcon will re-raise errors that do not inherit from ``falcon.HTTPError``
 | 
			
		||||
    unless you have registered a custom error handler for that type
 | 
			
		||||
    (see also: :ref:`falcon.API <api>`).
 | 
			
		||||
 | 
			
		||||
Speaking of error handling, when something goes horribly (or mildly) wrong,
 | 
			
		||||
you *could* manually set the error status, appropriate response headers, and
 | 
			
		||||
even an error body using the ``resp`` object. However, Falcon tries to make
 | 
			
		||||
things a bit easier by providing a set of exceptions you can raise when
 | 
			
		||||
something goes wrong. In fact, if Falcon catches any exception your responder
 | 
			
		||||
throws that inherits from ``falcon.HTTPError``, the framework will convert
 | 
			
		||||
that exception to an appropriate HTTP error response.
 | 
			
		||||
 | 
			
		||||
You may raise an instance of ``falcon.HTTPError``, or use any one
 | 
			
		||||
of a number of predefined error classes that try to do "the right thing" in
 | 
			
		||||
setting appropriate headers and bodies. Have a look at the docstrings for
 | 
			
		||||
setting appropriate headers and bodies. Have a look at the docs for
 | 
			
		||||
any of the following to get more information on how you can use them in your
 | 
			
		||||
API:
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -151,7 +151,9 @@ def compile_uri_template(template):
 | 
			
		||||
 | 
			
		||||
    Args:
 | 
			
		||||
        template: A Level 1 URI template. Method responders must accept, as
 | 
			
		||||
        arguments, all fields specified in the template (default '/').
 | 
			
		||||
            arguments, all fields specified in the template (default '/').
 | 
			
		||||
            Note that field names are restricted to ASCII a-z, A-Z, and
 | 
			
		||||
            the underscore '_'.
 | 
			
		||||
 | 
			
		||||
    Returns:
 | 
			
		||||
        (template_field_names, template_regex)
 | 
			
		||||
 
 | 
			
		||||
@@ -81,7 +81,14 @@ class Request(object):
 | 
			
		||||
        content_length (int): Value of the Content-Length header converted
 | 
			
		||||
            to an int, or *None* if the header is missing.
 | 
			
		||||
        stream: File-like object for reading the body of the request, if any.
 | 
			
		||||
            any.
 | 
			
		||||
 | 
			
		||||
            Note:
 | 
			
		||||
                If an HTML form is POSTed to the API using the
 | 
			
		||||
                *application/x-www-form-urlencoded* media type, Falcon
 | 
			
		||||
                will consume `stream` in order to parse the parameters
 | 
			
		||||
                and merge them into the query string parameters. In this
 | 
			
		||||
                case, the stream will be left at EOF.
 | 
			
		||||
 | 
			
		||||
        date (datetime): Value of the Date header, converted to a
 | 
			
		||||
            `datetime.datetime` instance. The header value is assumed to
 | 
			
		||||
            conform to RFC 1123.
 | 
			
		||||
@@ -463,6 +470,12 @@ class Request(object):
 | 
			
		||||
    def get_param(self, name, required=False, store=None):
 | 
			
		||||
        """Return the value of a query string parameter as a string.
 | 
			
		||||
 | 
			
		||||
        Note:
 | 
			
		||||
            If an HTML form is POSTed to the API using the
 | 
			
		||||
            *application/x-www-form-urlencoded* media type, the
 | 
			
		||||
            parameters from the request body will be merged into
 | 
			
		||||
            the query string parameters.
 | 
			
		||||
 | 
			
		||||
        Args:
 | 
			
		||||
            name (str): Parameter name, case-sensitive (e.g., 'sort')
 | 
			
		||||
            required (bool, optional): Set to True to raise HTTPBadRequest
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user