Commit Graph

20 Commits (44a28fda6875e9234e0c618f74bf7c191ca9cc41)

Author SHA1 Message Date
Dustin 44a28fda68 app: Add BaseApplication class
The `Application` class is now a sub-class of `BaseApplication`.
Applications that require more control of the framework's behavior can
extend `BaseApplication` instead of `Application`. The `BaseApplication`
class also provides some new features:

* `BaseApplication.setup_routes` is always called when an instance is
  created, and can be used to configure the request dispatcher
* `BaseApplication.update_config` updates the application configuration
  from a configuration file

The major difference between `BaseApplication` and `Application` is that
the latter requires a request dispatcher, while the former does not.
This pattern allows simple applications to construct a `Router` or root
object and then initialize the `Application` without needing to define a
sub-class.
2016-07-14 12:37:47 -05:00
Dustin da406fcce8 app: Refactor Application class
This commit breaks up the `Application.__call__` method into smaller methods
that can be overridden by subclasses. These methods allow customization of
various steps of the request/response handling process:

* `make_request`: Create the `Request` object from the WSGI environment
  dictionary. The default implementation creates a `milla.Request` object,
  copies the application configuration to its `config` attribute, and handles
  "emulated" HTTP methods from POST data.
* `resolve_path`: Locates a controller callable from the given path info. The
  default implementation calls the `resolve` method on the application's
  `dispatcher` attribute. If `UnresolvePath` is raised, it returns a callable
  that raises `HTTPNotFound`.
* `handle_error`: Called inside the exception handler when a controller
  callable raises an exception. The method should return a callable WSGI
  application (such as a `Response` or `WSGIHTTPException` object). To access
  the exception that was raised, use the `sys.exc_info` function. The default
  implementation returns the exception if it is an instance of
  `WSGIHTTPException`, or re-raises the exception otherwise. This allows
  middleware applications to handle the exception, if desired.
2015-04-25 12:42:42 -05:00
Dustin 86b19bb9e7 Whitespace cleanup 2015-04-15 19:45:17 -05:00
Dustin C. Hatch 230da47d5b app: Use _find_attr to locate controller's allowed_methods
Using the `milla.app.Application._find_attr` method to find the
`allowed_methods` of returned controller callables allows the attribute to be
defined e.g. on the class for instance methods, etc.
2015-02-19 20:37:39 -06:00
Dustin C. Hatch e6774204a6 app: Return an empty string for HEAD requests
Some WSGI servers, e.g. Werkzeug, unconditionally attempt to iterate over the
application response, even for HEAD requests. If `None` is returned, then the
server will crash in this case, because it is not iterable. This commit alters
the behavior of `milla.Application` to return an empty string, which is
iterable and has the same effect of not sending a body.
2015-02-19 20:01:05 -06:00
Dustin C. Hatch cf94a4d600 app: Fixed an issue with unicode responses in Python 2.7
If a controller callable returns a string, it needs to be wrapped in a
Response object. To determine if this is the case, the Application tests to
see if the returned object is an instance of `basestring`. Since `basestring`
doesn't exist in Python 3, only `str` is a valid return type.

Unfortunately, my way of testing whether the `basestring` type existed was
flawed. Instead of raising `NameError` when it doesn't exist,
`UnboundLocalError` (a subclass `NameError`) is *always* raised. Since the
exception handler sets `basestring` equal to `str` assuming this is Python 3,
most of the time this isn't a problem. If, however, the controller returns a
`unicode` object in Python 2, the `isinstance` call returns `False`, so the
response is not wrapped in a Response object.

Rather than try to reassign the `basestring` name, now we just use `_string`,
which will either be `basestring` (in Python 2) or `str` (in Python 3).

Apparently, the unit tests didn't cover this case...
2014-02-07 23:22:50 -06:00
Dustin C. Hatch fed7d0fb3d Merge default into py3k
--HG--
branch : py3k
2012-12-19 15:38:36 -06:00
Dustin C. Hatch d635e83431 Automatically create a Traverser instance if Application is given a root object 2012-11-30 22:47:06 -06:00
Dustin C. Hatch 17cac57721 Clean up __before__ and __after__ handling and make it Python 3-compatible
--HG--
branch : py3k
2012-11-30 14:37:02 -06:00
Dustin C. Hatch dc79fea9db Merged default into py3k
--HG--
branch : py3k
2012-11-30 13:19:55 -06:00
Dustin C. Hatch 5cd113ee46 Correctly use options_response for OPTIONS requests (fixes #5) 2012-11-30 13:13:17 -06:00
Dustin C. Hatch 5735d2b027 Better handling of string-type responses from controllers
--HG--
branch : py3k
2012-11-28 12:26:58 -06:00
Dustin C. Hatch 2980b438da Subclass WebOb Request and override relative_url (see #3) 2012-11-03 19:03:13 -05:00
Dustin C. Hatch 47cbd5c2d2 Patch requests that try to use POST "emulate" some other verb like PUT 2011-05-26 02:00:13 +00:00
Dustin C. Hatch 4c4ecbfe52 Respect the allowed methods of controller callables 2011-04-16 11:57:14 -05:00
Dustin C. Hatch 0fba1c95b9 Added licensing information and boilerplate messages 2011-04-05 23:47:44 -05:00
Dustin C. Hatch 303b0ff880 Added a `util` module and moved the `asbool` function there 2011-03-30 19:56:38 -05:00
Dustin C. Hatch 9fa85fac47 Added an icon and support for automatically serving favicon.ico 2011-03-27 15:24:41 -05:00
Dustin C. Hatch 9b30000a36 Support for `__before__` and `__after__` method calls for controllers
For convenience, a `Controller` class now exists from which all classes wanting to implement these methods should descend. This will allow sane cooperative multiple inheritance.
2011-03-27 14:54:42 -05:00
Dustin C. Hatch 6cf47a0339 Added a traversal dispatch method and cleaned up the router
* Created a dispatcher protocol for classes to implement for path resolution
* Implemented a traversal dispatcher
* Updated the router to implement the dispatcher protocol
* Added unit tests for both dispatchers
* Replaced the Controller class with an Application class
2011-03-26 23:35:31 -05:00